package com.gjm.tool.utils;

import org.springframework.core.io.ClassPathResource;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Description: 文件工具类
 * @Author: gjm
 * @date 2022/9/24 10:08
 * @Version 1.0
 */
public class FileUtil {
    /**
     * 读取resources下的文件
     * @return
     */
    public static String readResourcesFile(String filePath){
        ClassPathResource resource = new ClassPathResource(filePath);
        try {
            InputStream inputStream= resource.getInputStream();
            //将流转为字符串
            return FileUtil.streamToString(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * inputStream流转String
     * @param inputStream
     * @return
     */
    public static String streamToString(InputStream inputStream){
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        try {
            StringBuilder result = new StringBuilder();
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                result.append(line);
            }
            return result.toString();
        } catch (Exception e) {
            try {
                inputStream.close();
                bufferedReader.close();
            } catch (Exception e1) {
            }
        }
        return null;
    }

    /**
     * 清空已有的文件内容，以便下次重新写入新的内容
     **/
    public static synchronized void clearInfoForFile(String fileName) {
        // 文件保护
//        copyFile(Paths.get("/etc/conf/"+fileName),Paths.get("/etc/conf/"+fileName+"_backup"));

        System.out.println("----clear file ----");
        File file = new File(fileName);
        try {
            checkFolderAndFile(fileName);
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(file), "utf-8");
//            FileWriter fileWriter = new FileWriter(file);
            outputStreamWriter.write("");
            outputStreamWriter.flush();
            outputStreamWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 清空已有的文件内容，以便下次重新写入新的内容
     **/
    public static synchronized void clearInfoForFile(Path filePath) {
        System.out.println("----clear file ----");
        File file = filePath.toFile();
        try {
            if (!file.exists()) {
                file.createNewFile();
            }
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(file), "utf-8");
            outputStreamWriter.write("");
            outputStreamWriter.flush();
            outputStreamWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 文件后面追加信息
     **/
    public static synchronized void appendInfoToFile(String fileName, String info) {
//        System.out.println("----append file----");
        File file = new File(fileName);
        try {
            if (!file.exists()) {
                file.createNewFile();
            }
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(file,true), "utf-8");
//            FileWriter fileWriter = new FileWriter(file, true);
            info = info + System.getProperty("line.separator");
            outputStreamWriter.write(info);
            outputStreamWriter.flush();
            outputStreamWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 读取文件内容，文件中的内容为String
     **/
    public static List<String> readInfoFromFile(String fileName) throws IOException {
        File file = new File(fileName);
        if (!file.exists()) {
            //不存在则创建
            file.createNewFile();
        }
        List<String> resultStr = new ArrayList<String>();
        try {
            InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(file), "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            while (null != (str = bufferedReader.readLine())) {
                resultStr.add(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return resultStr;
    }

    /**
     * 读取文件内容，文件中的内容为String
     **/
    public static List<String> readInfoFromFile(Path filePath) throws IOException {
        File file = filePath.toFile();
        if (!file.exists()) {
            //不存在则创建
            file.createNewFile();
        }
        List<String> resultStr = new ArrayList<String>();
        try {
            InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(file), "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            while (null != (str = bufferedReader.readLine())) {
                resultStr.add(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return resultStr;
    }

    /**
     * 读取文件内容，文件中的内容为String
     **/
    public static String readInfoFromFileToStr(Path filePath) {
        File file = filePath.toFile();
        StringBuffer resultStr = new StringBuffer();
        try {
            if (!file.exists()) {
                //不存在则创建
                file.createNewFile();
            }
            InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(file), "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            while (null != (str = bufferedReader.readLine())) {
                resultStr.append(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return resultStr.toString();
    }

    /**
     * 重写文件
     **/
    public static synchronized void reloadFile(String fileName, String fileName_bak) {
        System.out.println("----reload file----");
        try {
            File file = new File(fileName);
            File file_bak = new File(fileName_bak);
            if (!file.exists()) {
                return;
            }
            if (!file_bak.exists()) {
                //不存在则创建
                file_bak.createNewFile();
            } else {
                clearInfoForFile(fileName_bak);
            }
            InputStreamReader fReader = new InputStreamReader(new FileInputStream(file),"UTF-8");
            BufferedReader bufferedReader = new BufferedReader(fReader);
            String str = null;
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(file_bak,true), "UTF-8");
            BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
//            FileWriter fileWriter = new FileWriter(outputStreamWriter, true);
            while (null != (str = bufferedReader.readLine())) {
                str = str.replaceAll("\\\\", "&&&");
                str = str + System.getProperty("line.separator");
                bufferedWriter.write(str);
            }
            bufferedWriter.flush();
            bufferedWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 备份文件回写
     **/
    public static synchronized void reloadBakFile(String fileName, String fileName_bak) {
        System.out.println("----backup file----");
        File file_bak = new File(fileName_bak);
        File file = new File(fileName);
        try {
            if (!file.exists()) {
                return;
            } else {
                clearInfoForFile(fileName);
            }
            if (!file_bak.exists()) {
                return;
            }
            BufferedReader bufferedReader = new BufferedReader(new FileReader(file_bak));
            String str = null;
            FileWriter fileWriter = new FileWriter(file, true);
            while (null != (str = bufferedReader.readLine())) {
                str = str.replaceAll("&&&", "\\\\");
                str = str + System.getProperty("line.separator");
                fileWriter.write(str);
            }
            fileWriter.flush();
            fileWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (file_bak.exists()) {
                file_bak.delete();
            }
        }
    }

    public static synchronized void deleteBak(String fileName_bak) {
        File file_bak = new File(fileName_bak);
        if (file_bak.exists()) {
            file_bak.delete();
        }
    }

    //=========

    /**
     * 删除文件(夹)
     * @param file
     */
    public static void delFile(Path file){
        if (Files.exists(file) && !Files.isDirectory(file)){
            try {
                Files.delete(file);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return;
        }
        try {
            Files.list(file).filter(item-> Files.exists(item)).forEach(FileUtil::delFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 复制目录
     *
     * @param file   目标地址
     * @param target 目的地址
     */
    public static synchronized void copyDiretory(Path file,Path target) {
        if (Files.isDirectory(file)){
            try {
                Files.list(file).forEach(item->{
                    copyDiretory(item,target);
                });
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else{
            try {
                // 在目标目录下创建备份目录
                Path directories = Files.createDirectories(Paths.get(target.toString() + file.getParent()));
                copyFile(file,Paths.get(directories.toString()+"/"+file.getFileName()));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 拷贝文件
     * @param file
     * @param target
     */
    public static synchronized void copyFile(Path file,Path target){
        System.out.println("----copy file----");
        try {
            if (Files.exists(file)){
                Files.copy(file,target, StandardCopyOption.REPLACE_EXISTING);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 备份网卡
     * @param backupFilePath
     */
    public static synchronized void backupNetCard(String backupFilePath){
        String path = "/etc/sysconfig/network-scripts/";
        try {
            Files.list(Paths.get(path)).forEach(System.out::println);
            long count = Files.list(Paths.get(path)).filter(item -> item.toString().contains("ifcfg-")).count();
            System.out.println("networkcard:"+count);
            Files.list(Paths.get(path)).filter(item -> item.toString().contains("ifcfg-")).forEach(item ->{
                try {
                    System.out.println("Paths.get(path+item):"+item);
                    System.out.println("Paths.get(backupFilePath+\"/\"+item):"+Paths.get(backupFilePath+"/"+item));
                    if (!Files.exists(Paths.get(backupFilePath+"/"+item))){
                        Files.createDirectories(Paths.get(backupFilePath+"/"+item).getParent());
                    }
                    copyFile(item, Paths.get(backupFilePath+"/"+item));
//                    copyFile(item,Paths.get(backupFilePath+"/"+item));
//                    Files.copy(item,Paths.get(backupFilePath+"/"+item));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取目录大小（文件/文件夹）
     *
     * @param directoryPath 目录
     * @return
     */
    public static synchronized long getDirectorySize(Path directoryPath) {
        List<Long> totalList = new ArrayList<>();
        List<Path> total = new ArrayList<>();
        try {
            getAllPath(directoryPath, total);
            for (Path path : total) {
                long size = getFileSize(path);
                System.out.println("遍历文件夹时,文件大小:"+path.getFileName()+"--"+size+" byte");
                if (size > 0) {
                    totalList.add(size);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return totalList.stream().collect(Collectors.summingLong(Long::longValue)).longValue();
    }

    /**
     * 获取所有Path
     *
     * @param directoryPath 目录
     * @param total         path集合
     */
    public static synchronized void getAllPath(Path directoryPath, List<Path> total) {
        try {
            if (Files.isDirectory(directoryPath)) {
                Stream<Path> list = Files.list(directoryPath);
                list.forEach(item -> {
                    if (Files.isDirectory(item)) {
                        getAllPath(item,total);
                    } else {
                        total.add(item);
                    }
                });
                list.close();
            } else {
                total.add(directoryPath);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取文件大小
     *
     * @param filePath 文件path
     * @return
     */
    public static synchronized long getFileSize(Path filePath) {
        try {
            File file = filePath.toFile();
            if (!file.exists() || !file.isFile()) {
                return -1;
            }
            return file.length();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return -1;
    }

    /**
     * 检测文件目录,不存在则创建
     * @param filePath 不包含文件名的路径
     * @return
     */
    public static Boolean checkFolder(Path filePath){
        try {
            File file = filePath.toFile();
            if (!file.exists()) {
                return file.mkdirs();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 检测文件目录,不存在则创建
     * @param filePath 不包含文件名的路径
     * @return
     */
    public static Boolean checkFolder(String filePath){
        try {
            File file = new File(filePath);
            if (!file.exists()) {
                return file.mkdirs();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 检测文件目录,不存在则创建
     * @param filePath 包含文件名的路径
     * @return
     */
    public static Boolean checkFileFolder(Path filePath){
        try {
            File file = filePath.toFile();
            File folderFile = file.getParentFile();
            if (!folderFile.exists()) {
                return file.getParentFile().mkdirs();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 检测文件目录,不存在则创建
     * @param filePath 包含文件名的路径
     * @return
     */
    public static Boolean checkFileFolder(String filePath){
        try {
            File file = new File(filePath);
            File folderFile = file.getParentFile();
            if (!folderFile.exists()) {
                return file.getParentFile().mkdirs();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 检测目录和文件,不存在则创建
     * @param filePath
     * @return
     */
    public static Boolean checkFolderAndFile(Path filePath){
        try {
            File file = filePath.toFile();
            if (checkFileFolder(filePath)){
                return file.createNewFile();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 检测目录和文件,不存在则创建
     * @param filePath
     * @return
     */
    public static Boolean checkFolderAndFile(String filePath){
        try {
            File file = new File(filePath);
            if (checkFileFolder(filePath)){
                return file.createNewFile();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 获取路径下所有path
     * @param filePath
     * @return
     */
    public static List<Path> getAllPath(String filePath) {
        List<Path> list = new ArrayList<>();
        try {
            Files.list(Paths.get(filePath)).forEach(item -> {
                list.add(item);
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 获取路径下所有path
     * @param path
     * @return
     */
    public static List<Path> getAllPath(Path path) {
        List<Path> list = new ArrayList<>();
        try {
            Files.list(path).forEach(item -> {
                list.add(item);
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }


    /**
     * 获取路径下所有文件夹名
     * @param path
     * @return
     */
    public static List<String> getAllFolderName(Path path) {
        List<String> list = new ArrayList<>();
        try {
            Files.list(path).forEach(item -> {
                list.add(item.getFileName().toString());
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 获取路径下所有文件夹名
     * @param filePath
     * @return
     */
    public static List<String> getAllFolderName(String filePath) {
        List<String> list = new ArrayList<>();
        try {
            Files.list(Paths.get(filePath)).forEach(item -> {
                list.add(item.getFileName().toString());
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 获取路径下所有文件path
     *
     * @param filePath
     * @return
     */
    public static List<Path> getAllFilePath(String filePath) {
        List<Path> list = new ArrayList<>();
        try {
            getAllPath(Paths.get(filePath), list);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

}
